import javax.sound.sampled.*;
import java.net.*;

public class RingPlayer {
	
	final short DIAL = 0;
	final short RING = 1;
	final short BUSY = 2;
	
    AudioFormat audioFormat;
    AudioInputStream audioInputStream;
    SourceDataLine sourceDataLine = null;
    boolean stopPlayback = false;
    URL url = null;
    
    private static RingPlayer ringPlayer = null;

    protected RingPlayer() {
    	
    }
    
    public static RingPlayer getInstance() {
    	if (ringPlayer == null) 
    		ringPlayer = new RingPlayer();
    	return ringPlayer;
    }

    public void playAudio(short type) {
    	this.closeLine();
    	try {
    		if (type == this.DIAL) 
    			url = this.getClass().getResource("dialtone.wav");
    		else if (type == this.RING)
    			url = this.getClass().getResource("ring.wav");
    		else if (type == this.BUSY)
    			url = this.getClass().getResource("busytone.wav");
    		
    		audioInputStream = AudioSystem.getAudioInputStream(url);
    		audioFormat = audioInputStream.getFormat();
    		System.out.println(audioFormat);
    		//sourceDataLine = (SourceDataLine)AudioSystem.getLine(dataLineInfo);
    		sourceDataLine = this.getSourceDataLine(audioFormat);
    		if (sourceDataLine != null) {
    			stopPlayback = false;
    			new PlayThread().start();
    		} 
    	} catch (Exception e) { e.printStackTrace(); }
    }

    public void closeLine() {
    	if (sourceDataLine != null) {
    		stopPlayback = true;
    		sourceDataLine.drain();
    		sourceDataLine.close();
    	}
    }
    
    private SourceDataLine getSourceDataLine(AudioFormat format) {
		try {
			DataLine.Info info = new DataLine.Info(SourceDataLine.class, format);
			for (Mixer.Info mi : AudioSystem.getMixerInfo()) {
				SourceDataLine dataline = null;
				try {
					Mixer mixer = AudioSystem.getMixer(mi);
					dataline = (SourceDataLine)mixer.getLine(info);
					dataline.open(format);
					dataline.start();
					return dataline;
				}
				catch (Exception e) {}
				if (dataline != null)
					try {
						dataline.close();
					}
					catch (Exception e) {}
			}
		}
		catch (Exception e) {}
		return null;
	}

    class PlayThread extends Thread {
        byte tempBuffer[] = new byte[10000];

        public void run() {
            try {
                sourceDataLine.open(audioFormat);
                sourceDataLine.start();
                int cnt;
                while(stopPlayback == false) {
                    cnt = audioInputStream.read(tempBuffer, 0, tempBuffer.length);
                    if(cnt == -1) {
                        //URL url = this.getClass().getResource("phone-ring.wav");
                        audioInputStream = AudioSystem.getAudioInputStream(url);
                        cnt = audioInputStream.read(tempBuffer,0,tempBuffer.length);
                    }
                    sourceDataLine.write(tempBuffer, 0, cnt);
                }
                sourceDataLine.drain();
                sourceDataLine.close();
            } catch(Exception e) { e.printStackTrace(); }
        }
    }
}
